//////////////////////////////////////////////////
// EASIM project
// easim.win.FileMenu
// 6/7/2007 6:39 PM
// Cong Liu
// gzcong@gmail.com

// Copyright (C) 2007
// All rights reserved.
// Refer to LICENSE of JIST (Java In Simulation Time) for terms and conditions of use.

package easim.win;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.swing.JOptionPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.LinkedList;

import easim.net.Node;
import easim.net.Field;
import jist.runtime.JistAPI.DoNotRewrite;

public class FileMenu extends JMenu implements DoNotRewrite
{
	private Frame frame;
	private JFileChooser fileChooser;

  protected class FileFilter1 extends FileFilter implements DoNotRewrite {
    public boolean accept (File file) {
      return file.getName().toLowerCase().endsWith(".txt") || 
        file.isDirectory();
    }
    public String getDescription() {
      return "Text files";
    }
  }

  protected class Interactor1 implements SynControler.Interactor, DoNotRewrite
  {
    public NodeInfo[] info;
    public void interactorAction() {
      for (int i = 0; i < info.length; ++ i) {
        Node node = frame.fieldPane.nodeFactory.create(info[i].id);
        SynControler.addNode(node, (int)info[i].x, (int)info[i].y);
      }
      Field.NODES += info.length;
      System.out.println("Field.NODES = " + Field.NODES);
      frame.fieldPane.repaint();
    }
  }

  protected class LoadNodesActionListener implements ActionListener, DoNotRewrite {
    public void actionPerformed(ActionEvent e) {
      fileChooser.rescanCurrentDirectory();
      int result = fileChooser.showOpenDialog(frame);
      if(result == JFileChooser.APPROVE_OPTION){
        File fp = fileChooser.getCurrentDirectory();
        String file = fp.getPath() + fp.separator + 
          fileChooser.getSelectedFile().getName();
        try {
          NodeInfo[] info = loadNodes(file);
          Interactor1 interactor = new Interactor1();
          interactor.info = info;
          SynControler.interact(interactor);
        } catch (Exception ex) {
          JOptionPane.showMessageDialog(frame, ex.getMessage(),
            "ERROR", JOptionPane.ERROR_MESSAGE);
          ex.printStackTrace(System.out);
        }
      }
    }
  }

  protected class SaveNodesActionListener implements ActionListener, DoNotRewrite {
    public void actionPerformed(ActionEvent e) {
      fileChooser.rescanCurrentDirectory();
      int result = fileChooser.showSaveDialog(frame);
      if(result == JFileChooser.APPROVE_OPTION){
        File fp = fileChooser.getCurrentDirectory();
        String file = fp.getPath() + fp.separator + 
          fileChooser.getSelectedFile().getName();
        file = file.toLowerCase();
        if (! file.endsWith(".txt")) file += ".txt";
        try {
          Node[] nodes = SynControler.getAllNodes();
          if (nodes.length > 0) saveNodes(file, nodes);
        } catch (Exception ex) {
          JOptionPane.showMessageDialog(frame, ex.getMessage(),
            "ERROR", JOptionPane.ERROR_MESSAGE);
          ex.printStackTrace(System.out);
        }
      }
    }
  }

  protected class NetDrawActionListener implements ActionListener, DoNotRewrite {
    public void actionPerformed(ActionEvent e) {
      int width = frame.fieldPane.getWidth();
      int height = frame.fieldPane.getHeight();
      easim.draw.Field field = SynControler.getField(width, height);
      easim.draw.Frame netdraw = new easim.draw.Frame();
      netdraw.setField(field);
    }
  }

  public FileMenu(String text, Frame frame) {
		super(text);
		this.frame = frame;
		this.fileChooser = new JFileChooser();
		fileChooser.setCurrentDirectory(new File("."));
		fileChooser.setFileFilter(new FileFilter1());
		JMenuItem loadNodes = new JMenuItem("Load Nodes");
		this.add(loadNodes);
		loadNodes.addActionListener(new LoadNodesActionListener());
		JMenuItem saveNodes = new JMenuItem("Save Nodes");
		this.add(saveNodes);
		saveNodes.addActionListener(new SaveNodesActionListener());
		JMenuItem netDraw = new JMenuItem("NetDraw");
		this.add(netDraw);
		netDraw.addActionListener(new NetDrawActionListener());
	}

  static class NodeInfo implements DoNotRewrite
  {
    public int id;
    public float x;
    public float y;
  }

  protected NodeInfo[] loadNodes(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(file));
    LinkedList list = new LinkedList();
    while (true) {
      String line = reader.readLine();
      if (line == null) break;
      line = line.trim();
      if (line.length() == 0) continue;
      String[] data = line.split(" ");
      NodeInfo info = new NodeInfo();
      info.id = Integer.parseInt(data[0]);
      info.x = Float.parseFloat(data[1]);
      info.y = Float.parseFloat(data[2]);
      list.addLast(info);
    }
    reader.close();
    return (NodeInfo[])list.toArray(new NodeInfo[0]);
  }

  protected void saveNodes(String file, Node[] nodes) throws IOException {
    for (int i = 0; i < nodes.length - 1; ++ i) {
      for (int j = nodes.length - 2; j >= i; -- j) {
        if (nodes[j].getId() > nodes[j + 1].getId()) {
          Node temp = nodes[j];
          nodes[j] = nodes[j + 1];
          nodes[j + 1] = temp;
        }
      }
    }
    BufferedWriter writer = new BufferedWriter(new FileWriter(file));
    for (int i = 0; i < nodes.length; ++ i) {
      writer.write(nodes[i].getId() + " " + nodes[i].getX() + " " + nodes[i].getY() + "\r\n");
    }
    writer.close();
  }

}
